﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;

namespace QL_Truong_Hoc
{
    public partial class frmQuanLyNhomQuyen : DevExpress.XtraEditors.XtraForm
    {
        private bool mblnEditState = false;
        private bool mblnViewMode = true;
        private int mintRoleID = 0;

        public frmQuanLyNhomQuyen()
        {
            InitializeComponent();
        }

        private void frmQuanLyNhomQuyen_Load(object sender, EventArgs e)
        {
            // TODO: This line of code loads data into the 'qLTHDataSet.tNhomQuyen' table. You can move, or remove it, as needed.
            this.tNhomQuyenTableAdapter.Fill(this.qLTHDataSet.tNhomQuyen);

            xSetButtonState(true);
            if (dgvNhomQuyen.RowCount > 0) dgvNhomQuyen.FocusedRowHandle = 0;
        }

        private bool xSetButtonState(bool blnState)
        {
            bool blnResult = false;
            try
            {
                btnThem.Enabled = blnState;
                btnSua.Enabled = blnState;
                btnXoa.Enabled = blnState;
                btnLuu.Enabled = !blnState;
                btnHuy.Enabled = !blnState;
                mblnViewMode = blnState;
                colRoleAllow.OptionsColumn.AllowEdit = !blnState;
                mblnEditState = false;

                return true;
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
            return blnResult;
        }

        private void btnThem_Click(object sender, EventArgs e)
        {
            try
            {
                txtTen.Text = "";
                txtTen.Enabled = true;

                treeQuyen.DataSource = xGetQuyenBlank();
                treeQuyen.ExpandAll();
                xSetButtonState(false);

                txtTen.Focus();
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
        }

        private void btnSua_Click(object sender, EventArgs e)
        {
            try
            {
                if (dgvNhomQuyen.FocusedRowHandle < 0) return;

                string strTen;

                mintRoleID = clsCommon.fncCnvNullToInt(dgvNhomQuyen.GetFocusedRowCellValue(colRoleID));
                strTen = clsCommon.fncCnvNullToString(dgvNhomQuyen.GetFocusedRowCellValue(colRoleName));
                txtTen.Text = strTen;
                txtTen.Enabled = true;

                xSetButtonState(false);
                mblnEditState = true;

                txtTen.Focus();
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
        }

        private void btnXoa_Click(object sender, EventArgs e)
        {
            try
            {
                if (dgvNhomQuyen.FocusedRowHandle < 0) return;

                bool blnSuccess = true;
                int intRoleID;
                List<DTO.TblUserDTO> lstUser;

                intRoleID = clsCommon.fncCnvNullToInt(dgvNhomQuyen.GetFocusedRowCellValue(colRoleID));
                lstUser = DAO.TblUserDAO.SelectWhere(Program.gobjDb, string.Format("RoleID = {0}", intRoleID));

                if (lstUser.Count > 0)
                {
                    clsCommon.fncMsgError("Vẫn có người dùng nằm trong nhóm quyền này. Hãy loại bỏ hết người dùng khỏi nhóm này trước khi xóa.");
                    return;
                }

                if (clsCommon.fncMsgConfirm("Bạn có chắc muốn xóa nhóm quyền đang được chọn?"))
                {
                    Program.gobjTrans = Program.gobjConn.BeginTransaction();

                    try
                    {
                        blnSuccess = blnSuccess && DAO.TNhomQuyenDAO.Delete(Program.gobjDb, Program.gobjTrans, intRoleID);
                        blnSuccess = blnSuccess && DAO.TNhomQuyen_QuyenDAO.Delete(Program.gobjDb, Program.gobjTrans, string.Format("RoleID = {0}", intRoleID));

                        //tNhomQuyenTableAdapter.Update(this.qLTHDataSet.tNhomQuyen);

                        //commit dữ liệu nếu không có gì lỗi, ngược lại thì rollback
                        if (blnSuccess)
                        {
                            Program.gobjTrans.Commit();
                            xSetButtonState(true);
                            txtTen.Text = "";
                        }
                        else { Program.gobjTrans.Rollback(); }
                    }
                    catch { Program.gobjTrans.Rollback(); blnSuccess = false; }

                    if (!blnSuccess)
                    {
                        clsCommon.fncMsgError("Xóa thất bại. Hãy thử lại sau.");
                    }
                    else
                    {
                        this.tNhomQuyenTableAdapter.Fill(this.qLTHDataSet.tNhomQuyen);
                        if (dgvNhomQuyen.RowCount > 0) dgvNhomQuyen.FocusedRowHandle = 0;
                    }
                }
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
        }

        private void btnLuu_Click(object sender, EventArgs e)
        {
            try
            {
                DTO.TNhomQuyenDTO objNhomQuyen;
                bool blnSuccess = true;

                if (!validProvider.Validate()) return;

                if (clsCommon.fncMsgConfirm("Dữ liệu sẽ được lưu. Bạn có chắc chắn?"))
                {
                    Program.gobjTrans = Program.gobjConn.BeginTransaction();
                    try
                    {
                        objNhomQuyen = new DTO.TNhomQuyenDTO();
                        objNhomQuyen.RoleID = mintRoleID;
                        objNhomQuyen.RoleName = txtTen.Text.Trim();

                        if (mblnEditState)
                        {
                            //sua
                            blnSuccess = blnSuccess && DAO.TNhomQuyenDAO.Update(Program.gobjDb, Program.gobjTrans, objNhomQuyen);

                            //xoa tat ca cac quyen trong nhom
                            blnSuccess = blnSuccess && DAO.TNhomQuyen_QuyenDAO.Delete(Program.gobjDb, Program.gobjTrans, string.Format("RoleID = {0}", mintRoleID));
                        }
                        else
                        {
                            //them moi     
                            mintRoleID = DAO.TNhomQuyenDAO.SelectNextIndex(Program.gobjDb);
                            blnSuccess = blnSuccess && DAO.TNhomQuyenDAO.Insert(Program.gobjDb, Program.gobjTrans, objNhomQuyen);
                        }

                        //them lai cac quyen trong nhom
                        blnSuccess = blnSuccess && xAddQuyenChiTiet(treeQuyen.Nodes, mintRoleID);
                        
                        //commit dữ liệu nếu không có gì lỗi, ngược lại thì rollback
                        if (blnSuccess)
                        {
                            Program.gobjTrans.Commit();
                            xSetButtonState(true);
                        }
                        else { Program.gobjTrans.Rollback(); }
                    }
                    catch { Program.gobjTrans.Rollback(); blnSuccess = false; }

                    if (!blnSuccess) { clsCommon.fncMsgError("Lưu dữ liệu bị lỗi. Hãy thử lại sau."); }
                    else
                    {
                        this.tNhomQuyenTableAdapter.Fill(this.qLTHDataSet.tNhomQuyen);
                        txtTen.Enabled = false;
                        if (dgvNhomQuyen.RowCount > 0) dgvNhomQuyen.FocusedRowHandle = 0;
                        Program.gevnApplication.RaiseRoleUpdated();
                    }
                }
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
        }

        private bool xAddQuyenChiTiet(DevExpress.XtraTreeList.Nodes.TreeListNodes objNodes, int intRoleID)
        {
            bool blnSuccess = true;

            try
            {
                if (objNodes == null) return true;

                int intQuyenID;
                bool blnAllow;
                DTO.TNhomQuyen_QuyenDTO objQuyenChiTiet;

                objQuyenChiTiet = new DTO.TNhomQuyen_QuyenDTO();

                for (int i = 0; i <= objNodes.Count - 1; i++)
                {
                    intQuyenID = clsCommon.fncCnvNullToInt(objNodes[i][colQU_ID.FieldName]);
                    blnAllow = clsCommon.fncCnvNullToBool(objNodes[i][colRoleAllow.FieldName]);

                    objQuyenChiTiet.QU_ID = intQuyenID;
                    objQuyenChiTiet.RoleAllow = blnAllow;
                    objQuyenChiTiet.RoleID = intRoleID;

                    blnSuccess = blnSuccess && DAO.TNhomQuyen_QuyenDAO.Insert(Program.gobjDb, Program.gobjTrans, objQuyenChiTiet);

                    if (objNodes[i].HasChildren)
                    {
                        blnSuccess = blnSuccess && xAddQuyenChiTiet(objNodes[i].Nodes, intRoleID);
                    }
                }

                return blnSuccess;
            }
            catch (Exception ex)
            {
                clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message);
                return false;
            }
        }

        private void btnHuy_Click(object sender, EventArgs e)
        {
            try
            {
                if (clsCommon.fncMsgConfirm("Dữ liệu sẽ không được lưu, bạn có chăc muốn hủy?"))
                {
                    //hủy thay đổi trên grid. lấy lại dữ liệu
                    txtTen.Text = "";
                    txtTen.Enabled = false;
                    xSetButtonState(true);

                    if (dgvNhomQuyen.RowCount > 0) { dgvNhomQuyen.FocusedRowHandle = 0; }
                    else treeQuyen.DataSource = null;
                }
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
        }

        private DataTable xGetQuyenBlank()
        {
            DataTable objData = null;

            try
            {
                objData = DAO.MQuyenDAO.SelectWhere(Program.gobjDb, "1 = 1", true);

                DataColumn objNewColumn = new DataColumn("RoleAllow", typeof(bool));
                objNewColumn.DefaultValue = true;
                objData.Columns.Add(objNewColumn);
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
            return objData;
        }

        private void dgvNhomQuyen_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            try
            {
                if (!mblnViewMode) return;
                if (e.FocusedRowHandle < 0) return;

                string strTen;
                int intRoleID;

                intRoleID = clsCommon.fncCnvNullToInt(dgvNhomQuyen.GetFocusedRowCellValue(colRoleID));
                strTen = clsCommon.fncCnvNullToString(dgvNhomQuyen.GetFocusedRowCellValue(colRoleName));

                txtTen.Text = strTen;

                treeQuyen.DataSource = DAO.clsDbAccess.fncGetNhomQuyen_Quyen(Program.gobjDb, intRoleID);
                treeQuyen.ExpandAll();
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
        }

        private void treeQuyen_CellValueChanged(object sender, DevExpress.XtraTreeList.CellValueChangedEventArgs e)
        {
            //try
            //{
            //    if (e.Column != colRoleAllow) return;

            //    //lay trang thai check
            //    bool blnState = clsCommon.fncCnvNullToBool(e.Value);

            //    //cac con se theo trang thai cua cha
            //    xTreeDownLineState(e.Node, blnState);

            //    //neu nut nay dc check thi cha no cung dc check. neu ko phai thi ko lam gi
            //    if (blnState) xTreeUpLineChecked(e.Node);
            //}
            //catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
        }

        private bool xTreeDownLineState(DevExpress.XtraTreeList.Nodes.TreeListNode objNode, bool blnState)
        {
            try
            {
                for (int i = 0; i <= objNode.Nodes.Count - 1; i++)
                {
                    objNode.Nodes[i].SetValue(colRoleAllow, blnState);
                    if (objNode.Nodes[i].HasChildren) xTreeDownLineState(objNode.Nodes[i], blnState);
                }
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
            return true;
        }

        private bool xTreeUpLineChecked(DevExpress.XtraTreeList.Nodes.TreeListNode objNode)
        {
            try
            {
                //neu ko co parent thi thoat
                if (objNode.ParentNode == null) return true;

                //neu co thi set la checked
                objNode.ParentNode.SetValue(colRoleAllow, true);
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
            return true;
        }

        private void treeQuyen_CellValueChanging(object sender, DevExpress.XtraTreeList.CellValueChangedEventArgs e)
        {
            try
            {
                if (e.Column != colRoleAllow) return;

                //lay trang thai check
                bool blnState = clsCommon.fncCnvNullToBool(e.Value);

                e.Node.SetValue(colRoleAllow, blnState);

                //cac con se theo trang thai cua cha
                xTreeDownLineState(e.Node, blnState);

                //neu nut nay dc check thi cha no cung dc check. neu ko phai thi ko lam gi
                if (blnState) xTreeUpLineChecked(e.Node);
            }
            catch (Exception ex) { clsCommon.fncMsgError(MethodBase.GetCurrentMethod().ReflectedType.Name, MethodBase.GetCurrentMethod().Name, ex.Message); }
        }
    }
}